package com.moss.cloud.auth.biz.expand.mobile;

import com.moss.cloud.auth.biz.exception.AuthErrorType;
import com.moss.cloud.auth.biz.utils.AuthHandel;
import com.moss.cloud.common.core.constant.Constant;
import com.moss.cloud.common.security.component.RedisTemplateOps;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.HashSet;

@Data
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
    private UserDetailsService userDetailsService;
    private RedisTemplateOps redisTemplateOps;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
        String mobile = (String) authenticationToken.getPrincipal();
        String code = (String) authenticationToken.getCredentials();
        String codeKey = Constant.SMS_CODE_KEY + mobile;
        String correctCode = (String) redisTemplateOps.get(codeKey);
        // 验证码比对
        AuthHandel.trueThrow(StringUtils.isBlank(correctCode) || !code.equals(correctCode)).throwMessage(AuthErrorType.SMS_CODE_ERROR.getMesg());
        redisTemplateOps.del(codeKey);
        UserDetails userDetails = userDetailsService.loadUserByUsername(mobile);
        AuthHandel.trueThrow(StringUtils.isBlank(userDetails.getUsername())).throwMessage(AuthErrorType.ACCT_PWD_ERROR.getMesg());
        SmsCodeAuthenticationToken result = new SmsCodeAuthenticationToken(userDetails, new HashSet<>());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
